#include "PiccoloApplication.h"

#include "Render/PiccoloRenderContext.h"
#include "PiccoloLog.h"

#include "ECS/PScene.h"

namespace Piccolo
{
    PiccoloAppContext PiccoloApplication::sAppContext;

    void PiccoloApplication::Start(int argc, char *argv[])
    {
        PiccoloLog::Init();
        ParseArgs(argc, argv);
        OnConfiguration(&mAppSettings);
        mWindow = PiccoloWindow::Create(mAppSettings.width, mAppSettings.height, mAppSettings.title);
        mRenderContext = std::make_shared<PiccoloRenderContext>(mWindow.get());
        sAppContext.app = this;
        sAppContext.renderContext = mRenderContext.get();
        OnInit();
        LoadScene();

        mStartTimePoint = std::chrono::steady_clock::now();
    }

    void PiccoloApplication::Tick()
    {
        mLastTimePoint = std::chrono::steady_clock::now();
        while (!mWindow->ShouldClose())
        {
            mWindow->PollEvents();

            float deltaTime = std::chrono::duration<float>(std::chrono::steady_clock::now() - mLastTimePoint).count();
            mLastTimePoint = std::chrono::steady_clock::now();
            mFrameIndex++;

            if (!bPause)
            {
                OnUpdate(deltaTime);
            }
            OnRender();

            mWindow->SwapBuffer();
        }
    }

    void PiccoloApplication::Stop()
    {
        UnloadScene();
        OnDestroy();
    }

    void PiccoloApplication::ParseArgs(int argc, char *argv[])
    {
    }

    bool PiccoloApplication::LoadScene(const std::string &filePath)
    {
        if (mScene)
        {
            UnloadScene();
        }
        mScene = std::make_unique<PScene>();
        mScene->OnInit();
        OnSceneInit(mScene.get());
        sAppContext.scene = mScene.get();
        return true;
    }

    void PiccoloApplication::UnloadScene()
    {
        if (mScene)
        {
            OnSceneDestroy(mScene.get());
            mScene.reset();
            sAppContext.scene = nullptr;
        }
    }
}
